package cn.minimelon.solon.service.excel.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import cn.minimelon.solon.domain.excel.*;
import cn.minimelon.solon.domain.utils.ExcelBeanMapper;
import cn.minimelon.solon.mapper.excel.*;
import cn.minimelon.solon.service.excel.PkgDefImportService;
import lombok.extern.slf4j.Slf4j;
import org.beetl.sql.solon.annotation.Db;
import org.noear.solon.annotation.Component;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class PkgDefImportServiceImpl implements PkgDefImportService {
    private static final String BRANCH_ID = "h00dc-27";
    private static final String ID_PREFIX = "2023000B";

    private static final String INIT_USER_ID = "0000";

    private static final String ZEROS = "0000000000000"; // 很多0

    private static final String DI_TYPE_GS1 = "gs1";

    private static final Integer GS1_LENGTH = 14;

    private static final String CODE_TYPE_QR = "0";

    @Db("writer")
    private YbGoodsMapper ybGoodsMapper;

    @Db("master")
    private HosGoodsInfoMapper hosGoodsInfoMapper;

    @Db("writer")
    private YbPkgDefMapper ybPkgDefMapper;

    @Db("writer")
    private YbShelfMapper ybShelfMapper;

    @Db("writer")
    private BranchGoodsPkgDefMapper branchGoodsPkgDefMapper;

    @Override
    public void start(String logicId, List<YNExcelVO> excelList) {
        List<HosGoodsInfo> hosGoodsInfoList = new ArrayList<>();
        List<String> goodsIdList = excelList.stream()
                .map(YNExcelVO::getHosGoodsId)
                .distinct()
                .collect(Collectors.toList());
        List<List<String>> idGroupList = ListUtil.partition(goodsIdList, 500);
        for (List<String> group : idGroupList) {
            List<HosGoodsInfo> tempGoodsList = hosGoodsInfoMapper.selectExtByIds(group);
            hosGoodsInfoList.addAll(tempGoodsList);
        }

        System.err.println(hosGoodsInfoList.size());
        List<String> idList = hosGoodsInfoList.stream().map(HosGoodsInfo::getId).collect(Collectors.toList());
        log.info("1.生成院边仓产品表目录");
        Map<String, Integer> hosExcelIdxMap = new HashMap<>();
        for (YNExcelVO pkgDef : excelList) {
            if (idList.contains(pkgDef.getHosGoodsId())) {
                pkgDef.setErrorFlag(0);
                hosExcelIdxMap.put(pkgDef.getHosGoodsId(), pkgDef.getIndex());
            } else {
                pkgDef.setErrorFlag(1);
                log.error("序号{}产品{}错误", pkgDef.getIndex(), pkgDef.getHosGoodsId());
            }
        }
        // 产品ID与院边仓产品ID映射
        Map<String, YbGoods> hosYBGoodsIdMap = new HashMap<>();
        for (HosGoodsInfo hosGoodsInfo : hosGoodsInfoList) {
            int excelIdx = hosExcelIdxMap.get(hosGoodsInfo.getId());
            YbGoods ygGoods = ExcelBeanMapper.INSTANCE.copyHosGoodsInfo(hosGoodsInfo);
            ygGoods.setId(getYbGoodsId(excelIdx));
            ygGoods.setLogicId(logicId);
            ygGoods.setCreateUser(INIT_USER_ID);
            ygGoods.setCreateTime(new Date());
            ygGoods.setLastModifiedUser(INIT_USER_ID);
            ygGoods.setLastModified(new Date());
            if (StrUtil.isEmpty(ygGoods.getCanPurchase())) {
                ygGoods.setCanPurchase("1");
            }
            if (ygGoods.getMade().contains("上海")) {
                log.error("产品ID：{} 产地：{}", ygGoods.getGoodsCode(), ygGoods.getMade());
                ygGoods.setMade("中国");
            } else if (ygGoods.getMade().contains("德国西门子")) {
                log.error("产品ID：{} 产地：{}", ygGoods.getGoodsCode(), ygGoods.getMade());
                ygGoods.setMade("德国");
            }
            ygGoods.setYbFlag("0");
            ygGoods.setVersion(0);
            try {
                ybGoodsMapper.insert(ygGoods);
                // log.info("序号{}生成院边仓产品：{}", excelIdx, ygGoods);
            } catch (Exception ex) {
                log.error("序号{}生成院边仓产品：{}\n {}", excelIdx, ygGoods, ex.getMessage());
            }

            /*
            log.info("2.生成院区产品表");
            BranchGoodsInfo branchGoodsInfo = ExcelBeanMapper.INSTANCE.copyYBGoodsInfo(ygGoods);
            String branchGoodsId = hosGoodsInfo.getId().replace("h0028", BRANCH_ID);
            log.info("序号{}院区产品ID：{}", excelIdx, branchGoodsId);
            branchGoodsInfo.setId(branchGoodsId);
            branchGoodsInfo.setBranchId("h0028-9");
            branchGoodsInfo.setFillDate(new Date());
            branchGoodsInfo.setVersion(0);
            branchGoodsInfo.setLastUpdateDatetime(new Date());
            branchGoodsInfo.setEffFlag("1");
            branchGoodsInfo.setPkgFlag("1");
            branchGoodsInfo.setYbFlag(0);
            log.info("序号{}生成院区产品：{}", excelIdx, branchGoodsInfo);
            branchGoodsInfoMapper.insert(branchGoodsInfo);
            */

            hosYBGoodsIdMap.put(hosGoodsInfo.getId(), ygGoods);
        }
        log.info("3.生成院边仓包定义");
        log.info("4.生成院区包定义");
        Map<String, List<YNExcelVO>> groupList = excelList.stream()
                .filter(o -> o.getErrorFlag() < 1)
                .collect(Collectors.groupingBy(YNExcelVO::getHosGoodsId));
        groupList.forEach((key, value) -> {
            YbGoods goodsInfo = hosYBGoodsIdMap.get(key);
            if (value.size() > 2) {
                YNExcelVO excelVO = value.get(0);
                log.error("序号：{}, 产品ID：{}", excelVO.getIndex(), key);
            } else if (value.size() == 2) {
                YNExcelVO excelOne = value.get(0);
                YNExcelVO excelTwo = value.get(1);
                boolean maxFlag = excelOne.getPkgQty() > excelTwo.getPkgQty();

                YbPkgDef pkgDefOne = buildPkgDef(excelOne, goodsInfo);
                pkgDefOne.setMaxPkgFlag(maxFlag ? 1 : 0);
                //log.info("序号：{}, 包定义：{}", excelOne.getIndex(), pkgDefOne);
                ybPkgDefMapper.insert(pkgDefOne);

                BranchGoodsPkgDef branOne = buildBranchDef(pkgDefOne, excelOne.getBranchGoodsId());
                //log.info("序号：{}, 院区包定义：{}", excelOne.getIndex(), branOne);
                branchGoodsPkgDefMapper.insert(branOne);

                YbPkgDef pkgDefTwo = buildPkgDef(excelTwo, goodsInfo);
                pkgDefTwo.setMaxPkgFlag(maxFlag ? 0 : 1);
                //log.info("序号：{}, 包定义：{}", excelTwo.getIndex(), pkgDefTwo);
                ybPkgDefMapper.insert(pkgDefTwo);

                BranchGoodsPkgDef branTwo = buildBranchDef(pkgDefTwo, excelTwo.getBranchGoodsId());
                //log.info("序号：{}, 院区包定义：{}", excelOne.getIndex(), branTwo);
                branchGoodsPkgDefMapper.insert(branTwo);
            } else {
                YNExcelVO excelOne = value.get(0);
                YbPkgDef pkgDefOne = buildPkgDef(excelOne, goodsInfo);
                pkgDefOne.setMaxPkgFlag(1);
                //log.info("序号：{}, 包定义：{}", excelOne.getIndex(), pkgDefOne);
                ybPkgDefMapper.insert(pkgDefOne);

                BranchGoodsPkgDef branOne = buildBranchDef(pkgDefOne, excelOne.getBranchGoodsId());
                //log.info("序号：{}, 院区包定义：{}", excelOne.getIndex(), branOne);
                branchGoodsPkgDefMapper.insert(branOne);
            }
        });
        log.info("存储数据库成功！");
    }

    @Override
    public void refreshShelf(String logicId) {
        List<YbShelf> shelfList = ybShelfMapper.createLambdaQuery()
                .andEq(YbShelf::getLogicId, logicId)
                .andEq(YbShelf::getStockType, "1")
                .select();
        // String.format("%s%05d", "HW2022000B", idx)
        for (int i = 0; i < shelfList.size(); i++) {
            String id = String.format("%s%05d", "HW2022000B", i + 1);
            ybShelfMapper.updateId(shelfList.get(i).getId(), id);
        }
    }

    private BranchGoodsPkgDef buildBranchDef(YbPkgDef pkgDef, String branchGoodsId) {
        BranchGoodsPkgDef branDef = ExcelBeanMapper.INSTANCE.copyYBPkgDef(pkgDef);
        branDef.setId(pkgDef.getId() + BRANCH_ID.substring(BRANCH_ID.indexOf("-") + 1));
        branDef.setBranchId(BRANCH_ID);
        branDef.setLevelCode("9");
        branDef.setBranchGoodsId(branchGoodsId);
        branDef.setEffFlag("1");
        branDef.setPkgUperQty(0D);
        branDef.setPkgLowQty(0D);
        branDef.setVersion(0);
        branDef.setLastUpdateDatetime(new Date());
        branDef.setFillDate(new Date());
        branDef.setCreateTime(new Date());
        branDef.setLastModified(new Date());
        return branDef;
    }

    private YbPkgDef buildPkgDef(YNExcelVO excel, YbGoods goodsInfo) {
        YbPkgDef pkgDef = ExcelBeanMapper.INSTANCE.copyYBGoodsInfoDef(goodsInfo);
        pkgDef.setId(getYbDefId(excel.getIndex()));
        pkgDef.setPkgType("16");
        pkgDef.setPkgName(excel.getPkgName());
        pkgDef.setGoodsQty(excel.getPkgQty());
        pkgDef.setMaxQty(0);
        pkgDef.setMinQty(0);
        pkgDef.setDiType(DI_TYPE_GS1);
        pkgDef.setDiUse(getDiUse(goodsInfo, excel.getIndex()));
        pkgDef.setCodeType(CODE_TYPE_QR);
        pkgDef.setTbStatus(1);
        pkgDef.setVersion(0);
        pkgDef.setDelFlag(0);
        pkgDef.setCreateTime(new Date());
        pkgDef.setLastModified(new Date());
        return pkgDef;
    }

    private String getYbDefId(int idx) {
        return String.format("%s%05d", "C" + ID_PREFIX, idx);
    }

    private String getYbGoodsId(int idx) {
        return String.format("%s%06d", "G" + ID_PREFIX, idx);
    }

    private Integer getShortId(String goodsId) {
        String shortCode = goodsId.substring(goodsId.lastIndexOf("-") + 1);
        return Integer.parseInt(shortCode);
    }

    private String getDiUse(YbGoods goodsInfo, int count) {
        if (StrUtil.isNotEmpty(goodsInfo.getGoodsDi())) {
            return goodsInfo.getGoodsDi();
        } else {
            String logicId = goodsInfo.getLogicId();
            String bIdx = logicId.substring(logicId.lastIndexOf("0") + 1);
            String code = bIdx + "0" + goodsInfo.getSpdGoodsCode() + (count % 2);
            return ZEROS.substring(0, GS1_LENGTH - code.length()) + code;
        }
    }
}
